package com.topisv.tms.service.shipped;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.mapper.BeanMapper;

import com.topisv.tms.entity.BackupTask;
import com.topisv.tms.entity.BackupTaskOrdeno;
import com.topisv.tms.entity.BackupTaskSku;
import com.topisv.tms.entity.EdiOrderItem;
import com.topisv.tms.entity.ShippedBatch;
import com.topisv.tms.entity.ShippedBox;
import com.topisv.tms.entity.ShippedBoxOrdeno;
import com.topisv.tms.entity.ShippedBoxSkus;
import com.topisv.tms.entity.dto.ShippedBoxDTO;
import com.topisv.tms.repository.BackupTaskDao;
import com.topisv.tms.repository.BackupTaskOrdenoDao;
import com.topisv.tms.repository.BackupTaskSkuDao;
import com.topisv.tms.repository.EdiOrderItemDao;
import com.topisv.tms.repository.ShippedBatchDao;
import com.topisv.tms.repository.ShippedBoxDao;
import com.topisv.tms.repository.ShippedBoxOrdenoDao;
import com.topisv.tms.repository.ShippedBoxSkusDao;
import com.topisv.tms.utils.BackupTaskRule;

//Spring Bean的标识.
@Component
// 默认将类中的所有public函数纳入事务管理.
@Transactional(readOnly = true)
public class ShippedBoxService {

	@Autowired
	private ShippedBoxDao shippedBoxDao;
	@Autowired
	private ShippedBoxSkusDao shippedBoxSkusDao;
	@Autowired
	private ShippedBatchDao shippedBatchDao;
	@Autowired
	private BackupTaskSkuDao backupTaskSkuDao;
	@Autowired
	private BackupTaskDao backupTaskDao;
	@Autowired
	private BackupTaskOrdenoDao backupTaskOrdenoDao;
	@Autowired
	private EdiOrderItemDao ediOrderItemDao;
	@Autowired
	private ShippedBoxOrdenoDao shippedBoxOrdenoDao;
	
	
	/**
	 * 减少箱子的商品
	 * @param boxCode
	 * @param waybillNo
	 * @return
	 * @throws Exception
	 */
	@Transactional(readOnly = false)
	public ShippedBoxDTO reduceWaybillNo(String boxCode, String waybillNo)throws Exception{
		ShippedBoxDTO shippedBoxDTO=null;
		try {
			ShippedBoxOrdeno shippedBoxOrdeno=shippedBoxOrdenoDao.findByBoxCodeAndWaybillNo(boxCode, waybillNo);
			if(shippedBoxOrdeno==null||"pending".equals(shippedBoxOrdeno.getStatus())){
				shippedBoxDTO=new ShippedBoxDTO();
				shippedBoxDTO.setStatus("-1");
				shippedBoxDTO.setReserve("该订单不属于该箱子");
				return shippedBoxDTO;
			}
			shippedBoxOrdeno.setStatus("pending");
			List<EdiOrderItem> ediOrderItem = ediOrderItemDao.findByWaybillNo(waybillNo);
			int skuQty=0;
			// 删除箱子明细
			for (EdiOrderItem e : ediOrderItem) {
				skuQty+=e.getQty();
				ShippedBoxSkus shippedBoxSkus=shippedBoxSkusDao.findByBoxCodeAndSkuId(boxCode, e.getSku());
				if(shippedBoxSkus.getRealQty()<e.getQty()){
					throw new Exception(waybillNo+"数量不正确!");
				}
				if(shippedBoxSkus.getRealQty()==e.getQty()){//要是商品数量相等的话 直接删除
					shippedBoxSkusDao.delete(shippedBoxSkus.getId());
					continue;
				}
				shippedBoxSkus.setRealQty(shippedBoxSkus.getRealQty()-e.getQty());
				shippedBoxSkusDao.save(shippedBoxSkus);
			}
			ShippedBox shippedBox=shippedBoxDao.findByBoxCode(boxCode);
			if(shippedBox.getSkuQty()<skuQty){
				throw new Exception(boxCode+"数量不正确!");
			}
			if(shippedBox.getSkuQty()==skuQty){//要是商品数量相等的话 直接删除
				shippedBoxOrdeno.setBoxCode(null);
				shippedBoxDao.delete(shippedBox.getId());
				return null;
			}
			shippedBox.setSkuQty(shippedBox.getSkuQty()-skuQty);
			shippedBox.setOrdenoQty(shippedBox.getOrdenoQty()-1);
			ShippedBatch shippedBatch=shippedBatchDao.findByBatchCode(shippedBox.getBatchCode());
			if("finish".equals(shippedBatch.getBoxStatus())){
				shippedBatch.setBoxStatus("pending");
				shippedBatchDao.save(shippedBatch);
			}
			shippedBoxOrdenoDao.save(shippedBoxOrdeno);
			shippedBoxDao.save(shippedBox);
			shippedBoxDTO = BeanMapper.map(shippedBox, ShippedBoxDTO.class);
			return shippedBoxDTO;
		} catch (Exception e) {
			throw e;
		}
		
	}

	/**
	 * 中转发装箱操作
	 * 
	 * @param batchCode
	 * @param boxCode
	 * @param waybillNo
	 * @return
	 * @throws Exception
	 */
	@Transactional(readOnly = false)
	public ShippedBoxDTO addShippedBoxOrdeno(String batchCode, String boxCode,
			String waybillNo, String jobuuid) throws Exception {
		ShippedBatch shippedBatch = null;
		ShippedBoxDTO shippedBoxDTO = null;
		ShippedBox shippedBox = null;
		BackupTaskOrdeno backupTaskOrdeno = null;
		try {
			shippedBatch = shippedBatchDao.findByBatchCode(batchCode);
			// 验证开始
			if (shippedBatch == null) {
				shippedBoxDTO = new ShippedBoxDTO();
				shippedBoxDTO.setStatus("-1");
				shippedBoxDTO.setReserve("该出库批次不存在");
				return shippedBoxDTO;
			}
			if (!jobuuid.equals(shippedBatch.getJobuuid())) {
				shippedBoxDTO = new ShippedBoxDTO();
				shippedBoxDTO.setStatus("-1");
				shippedBoxDTO.setReserve("该出库批次任务不属于该用户");
				return shippedBoxDTO;
			}
			backupTaskOrdeno = backupTaskOrdenoDao.findByWaybillNo(waybillNo);// 验证运单号
			if (backupTaskOrdeno == null) {
				shippedBoxDTO = new ShippedBoxDTO();
				shippedBoxDTO.setStatus("-1");
				shippedBoxDTO.setReserve("该运单号不存在");
				return shippedBoxDTO;
			}
			if (!batchCode.equals(backupTaskOrdeno.getBatchCode())) {// 验证该订单号是否属于该出库批次
				shippedBoxDTO = new ShippedBoxDTO();
				shippedBoxDTO.setStatus("-1");
				shippedBoxDTO.setReserve("该订单不属于该出库批次");
				return shippedBoxDTO;
			}
			ShippedBoxOrdeno shippedBoxOrdeno = shippedBoxOrdenoDao
					.findByWaybillNo(waybillNo);
			if (shippedBoxOrdeno == null) {
				shippedBoxDTO = new ShippedBoxDTO();
				shippedBoxDTO.setStatus("-1");
				shippedBoxDTO.setReserve("数据有误");
				return shippedBoxDTO;
			}
			if ("finish".equals(shippedBoxOrdeno.getStatus())) {
				shippedBoxDTO = new ShippedBoxDTO();
				shippedBoxDTO.setStatus("-1");
				shippedBoxDTO.setReserve("该订单已经入箱箱子编号为:"
						+ shippedBoxOrdeno.getBoxCode());
				return shippedBoxDTO;
			}
			
			List<EdiOrderItem> ediOrderItem = ediOrderItemDao.findByWaybillNo(waybillNo);
			int skuQty=0;
			// 保存箱子明细
			for (EdiOrderItem e : ediOrderItem) {
				ShippedBoxSkus shippedBoxSkus = shippedBoxSkusDao
						.findByBoxCodeAndSkuId(boxCode, e.getSku());
				skuQty+=e.getQty();
				if (shippedBoxSkus == null) {
					shippedBoxSkus = new ShippedBoxSkus();
					shippedBoxSkus.setBackupTaskCode(shippedBatch.getBackupTaskCode());
					shippedBoxSkus.setBatchCode(shippedBatch.getBatchCode());
					shippedBoxSkus.setBoxCode(boxCode);
					shippedBoxSkus.setCheckQty(0);
					shippedBoxSkus.setRealQty(e.getQty());
					shippedBoxSkus.setSkuId(e.getSku());
					shippedBoxSkus.setUpdateDate(new Date());
					shippedBoxSkus.setStatus("pending");
					shippedBoxSkus.setCreateDate(new Date());
				} else {
					shippedBoxSkus.setRealQty(shippedBoxSkus.getRealQty()+ e.getQty());
				}
				shippedBoxSkusDao.save(shippedBoxSkus);
			}
			shippedBox = shippedBoxDao.findByBoxCode(boxCode);// 查找箱子
			if (shippedBox == null) {
				shippedBox = new ShippedBox();
				Date now = new Date();
				shippedBox.setBatchCode(batchCode);
				shippedBox.setBoxCode(boxCode);
				shippedBox.setCreateDate(now);
				shippedBox.setUpdateDate(now);
				shippedBox.setSkuQty(skuQty);
				shippedBox.setOrdenoQty(1);
				shippedBox.setType(shippedBatch.getType());
				shippedBox.setStatus("finish");
				shippedBatch.setBoxQty(shippedBatch.getBoxQty() + 1);
			}else{
				shippedBox.setOrdenoQty(1+shippedBox.getOrdenoQty());
				shippedBox.setSkuQty(shippedBox.getSkuQty()+skuQty);
			}
			shippedBoxDao.save(shippedBox);
			shippedBoxOrdeno.setBoxCode(boxCode);
			shippedBoxOrdeno.setStatus("finish");
			shippedBoxOrdenoDao.save(shippedBoxOrdeno);
			shippedBoxDTO = BeanMapper.map(shippedBox, ShippedBoxDTO.class);
			shippedBoxDTO.setStatus("1");
			shippedBoxDTO.setReserve("入箱成功");
			shippedBoxDTO.setIndex(backupTaskOrdeno.getOrdeno());
			//判断该出库批次是否全部装箱完成
			List<ShippedBoxOrdeno> shippedBoxOrdenos=shippedBoxOrdenoDao.findByBatchCodeAndStatus(batchCode, "pending");
			if(shippedBoxOrdenos.isEmpty()){
				shippedBatch.setBoxStatus("finish");
				shippedBoxDTO.setStatus("2");
				shippedBoxDTO.setReserve("入箱成功：该出库批次装箱完成");
			}
			shippedBatchDao.save(shippedBatch);// 增加批次箱子数量
			return shippedBoxDTO;
		} catch (Exception e) {
			throw e;
		}

	}

	/**
	 * 往一个箱子中新增商品
	 * 
	 * @param boxCode
	 * @param skuId
	 * @return
	 * @throws Exception
	 */
	@Transactional(readOnly = false)
	public ShippedBoxDTO addShippedBoxSkuId(String boxCode, String skuId)
			throws Exception {
		ShippedBox shippedBox = null;
		ShippedBatch shippedBatch = null;
		BackupTaskSku backupTaskSku = null;
		try {
			shippedBox = shippedBoxDao.findByBoxCode(boxCode);
			if (shippedBox == null) {
				return null;
			}
			ShippedBoxDTO shippedBoxDTO = BeanMapper.map(shippedBox,
					ShippedBoxDTO.class);
			shippedBatch = shippedBatchDao.findByBatchCode(shippedBox
					.getBatchCode());
			backupTaskSku = backupTaskSkuDao.findByBackupTaskCodeAndSkuId(
					shippedBatch.getBackupTaskCode(), skuId);
			if (backupTaskSku == null) {
				return null;
			}
			if ("finish".equals(backupTaskSku.getStatus())) {
				shippedBoxDTO.setStatus("-1");
				shippedBoxDTO.setReserve("该商品已经完全装箱");
				return shippedBoxDTO;
			}
			backupTaskSku.setCheckQty(backupTaskSku.getCheckQty() + 1);
			if (backupTaskSku.getRealQty() == backupTaskSku.getCheckQty()) {
				backupTaskSku.setStatus("finish");
			} else {
				backupTaskSku.setStatus("pending");
			}
			ShippedBoxSkus shippedBoxSkus = shippedBoxSkusDao
					.findByBoxCodeAndSkuId(boxCode, skuId);
			if (shippedBoxSkus == null) {// 该箱子中没有该商品信息
				shippedBoxSkus = new ShippedBoxSkus();
				shippedBoxSkus.setBoxCode(boxCode);
				shippedBoxSkus.setSkuId(skuId);
				shippedBoxSkus.setRealQty(1);
				shippedBoxSkus.setBatchCode(shippedBox.getBatchCode());
				shippedBoxSkus.setBackupTaskCode(shippedBatch
						.getBackupTaskCode());
				shippedBox.setSkuType(shippedBox.getSkuType() + 1);
			} else {
				shippedBoxSkus.setUpdateDate(new Date());
				shippedBoxSkus.setRealQty(shippedBoxSkus.getRealQty() + 1);
			}
			shippedBox.setSkuQty(shippedBox.getSkuQty() + 1);
			shippedBoxSkusDao.save(shippedBoxSkus);
			shippedBoxDao.save(shippedBox);
			backupTaskSkuDao.save(backupTaskSku);
			shippedBoxDTO = BeanMapper.map(shippedBox, ShippedBoxDTO.class);
			BackupTask backupTask = backupTaskDao
					.findByBackupTaskCode(shippedBatch.getBackupTaskCode());
			List<BackupTaskSku> backupTaskSkus = backupTaskSkuDao
					.findByBackupTaskCodeAndStatus(
							shippedBatch.getBackupTaskCode(), "pending");
			if (backupTaskSkus.isEmpty()) {
				backupTask.setStatus("finish");
				shippedBatch.setBoxStatus("finish");
				shippedBoxDTO.setStatus("finish");
				shippedBoxDTO.setReserve("封箱完毕");
				shippedBatchDao.save(shippedBatch);
				backupTaskDao.save(backupTask);
			}

			return shippedBoxDTO;
		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * 箱子减少商品
	 * 
	 * @param boxCode
	 * @param skuId
	 * @return
	 * @throws Exception
	 */
	@Transactional(readOnly = false)
	public ShippedBoxDTO reduceShippedBoxSkuId(String boxCode, String skuId)
			throws Exception {
		ShippedBox shippedBox = null;
		ShippedBatch shippedBatch = null;
		BackupTaskSku backupTaskSku = null;
		ShippedBoxSkus shippedBoxSkus = null;
		try {
			shippedBox = shippedBoxDao.findByBoxCode(boxCode);// 判断箱子是否存在
			if (shippedBox == null) {
				return null;
			}
			ShippedBoxDTO shippedBoxDTO = BeanMapper.map(shippedBox,
					ShippedBoxDTO.class);
			shippedBatch = shippedBatchDao.findByBatchCode(shippedBox
					.getBatchCode());// 判断出库批次是否存在
			backupTaskSku = backupTaskSkuDao.findByBackupTaskCodeAndSkuId(
					shippedBatch.getBackupTaskCode(), skuId);// 判断该商品是否存在该拣货任务
			if (backupTaskSku == null) {
				shippedBoxDTO.setStatus("-1");
				shippedBoxDTO.setReserve("该商品不属于该拣货任务");
				return shippedBoxDTO;
			}
			shippedBoxSkus = shippedBoxSkusDao.findByBoxCodeAndSkuId(boxCode,
					skuId);// 该箱子中没有该商品信息
			if (shippedBoxSkus == null) {
				shippedBoxDTO.setStatus("-1");
				shippedBoxDTO.setReserve("该商品不属于该箱子");
				return shippedBoxDTO;
			}

			shippedBox.setSkuQty(shippedBox.getSkuQty() - 1);
			shippedBoxSkus.setRealQty(shippedBoxSkus.getRealQty() - 1);
			if (shippedBox.getSkuQty() == 0) {
				shippedBoxDao.delete(shippedBox);// 如果箱子中只有一个商品则删除该箱子
				shippedBoxSkusDao.delete(shippedBoxSkus);
				backupTaskSku.setCheckQty(backupTaskSku.getCheckQty() - 1);
				backupTaskSku.setStatus("pending");
				backupTaskSkuDao.save(backupTaskSku);
				shippedBoxDTO.setStatus("2");
				shippedBoxDTO.setReserve("该箱子只有一件商品并且已经删除");
				return shippedBoxDTO;
			} else if (shippedBoxSkus.getRealQty() == 0) {
				backupTaskSku.setCheckQty(backupTaskSku.getCheckQty() - 1);
				backupTaskSku.setStatus("pending");
				shippedBox.setSkuType(shippedBox.getSkuType() - 1);
				shippedBoxDao.save(shippedBox);
				backupTaskSkuDao.save(backupTaskSku);
				shippedBoxSkusDao.delete(shippedBoxSkus);
			} else {
				shippedBoxSkus.setUpdateDate(new Date());
				backupTaskSku.setCheckQty(backupTaskSku.getCheckQty() - 1);
				backupTaskSku.setStatus("pending");
				shippedBoxSkusDao.save(shippedBoxSkus);
				shippedBoxDao.save(shippedBox);
				backupTaskSkuDao.save(backupTaskSku);
			}
			shippedBoxDTO = BeanMapper.map(shippedBox, ShippedBoxDTO.class);
			BackupTask backupTask = backupTaskDao
					.findByBackupTaskCode(shippedBatch.getBackupTaskCode());
			if ("finish".equals(backupTask.getStatus())) {
				backupTask.setStatus("pending");
				backupTaskDao.save(backupTask);
			}
			if("finish".equals(shippedBatch.getBoxStatus())){
				shippedBatch.setBoxStatus("pending");
				shippedBoxDTO.setStatus("pending");
				shippedBatchDao.save(shippedBatch);
			}

			return shippedBoxDTO;
		} catch (Exception e) {
			throw e;
		}
	}

	public ShippedBox findByBoxCode(String boxCode) {
		return shippedBoxDao.findByBoxCode(boxCode);
	}

	public List<ShippedBox> findByBatchCode(String batchCode) {
		return shippedBoxDao.findByBatchCode(batchCode);
	}

	@Transactional(readOnly = false)
	public ShippedBox save(ShippedBox arg0) {
		return shippedBoxDao.save(arg0);
	}

	@Transactional(readOnly = false)
	public List<ShippedBox> save(List<ShippedBox> arg0) {
		return (List<ShippedBox>) shippedBoxDao.save(arg0);
	}

	/**
	 * 商品装箱
	 * 
	 * @param backupTaskCode
	 * @return
	 * @throws Exception
	 */
	@Transactional(readOnly = false)
	public ShippedBox excuteShippedBox(String backupTaskCode) throws Exception {
		ShippedBox shippedBox = null;
		List<ShippedBoxSkus> shippedBoxSkus = null;
		int skuQty = 0;
		try {
			String boxCode = BackupTaskRule.getBoxCode(backupTaskCode);// 箱子条码
			BackupTask backupTask = backupTaskDao.findByBackupTaskCode(backupTaskCode);
			shippedBoxSkus = shippedBoxSkusDao.findByBoxCodeAndBackupTaskCode(null, backupTaskCode);
			ShippedBatch shippedBatch = shippedBatchDao.findByBackupTaskCode(backupTaskCode);
			if (shippedBoxSkus.isEmpty()) {
				return null;
			}
			for (ShippedBoxSkus obj : shippedBoxSkus) {
				skuQty += obj.getRealQty();
				obj.setBoxCode(boxCode);
				shippedBoxSkusDao.save(obj);
			}
			shippedBox = new ShippedBox();
			shippedBox.setCreateDate(new Date());
			shippedBox.setUpdateDate(new Date());
			shippedBox.setBoxCode(boxCode);
			shippedBox.setSkuQty(skuQty);
			shippedBox.setStatus("pending");
			shippedBox.setType(shippedBatch.getType());
			shippedBox.setBatchCode(shippedBatch.getBatchCode());
			shippedBox.setSkuType(shippedBoxSkus.size());
			shippedBoxDao.save(shippedBox);
			shippedBatch.setBoxQty(shippedBatch.getBoxQty() + 1);// 箱子数量增加
			if ("finish".equals(backupTask.getStatus())) {
				shippedBatch.setBoxStatus("finish");
			}
			shippedBatchDao.save(shippedBatch);
		} catch (Exception e) {
			throw e;
		}
		return shippedBox;
	}
	
	@Transactional(readOnly = false)
	public ShippedBox excuteShippedBox(String backupTaskCode,String boxCode) throws Exception {
		ShippedBox shippedBox = null;
		List<ShippedBoxSkus> shippedBoxSkus = null;
		int skuQty = 0;
		try {
			BackupTask backupTask = backupTaskDao.findByBackupTaskCode(backupTaskCode);
			shippedBoxSkus = shippedBoxSkusDao.findByBoxCodeAndBackupTaskCode( null, backupTaskCode);
			ShippedBatch shippedBatch = shippedBatchDao.findByBackupTaskCode(backupTaskCode);
			if (shippedBoxSkus.isEmpty()) {
				return null;
			}
			for (ShippedBoxSkus obj : shippedBoxSkus) {
				skuQty += obj.getRealQty();
				obj.setBoxCode(boxCode);
				BackupTaskSku backupTaskSku=backupTaskSkuDao.findByBackupTaskCodeAndSkuId(backupTaskCode, obj.getSkuId());
				backupTaskSku.setCheckQty(obj.getRealQty());
				backupTaskSkuDao.save(backupTaskSku);
				shippedBoxSkusDao.save(obj);
			}
			shippedBox = new ShippedBox();
			shippedBox.setCreateDate(new Date());
			shippedBox.setUpdateDate(new Date());
			shippedBox.setBoxCode(boxCode);
			shippedBox.setSkuQty(skuQty);
			shippedBox.setStatus("pending");
			shippedBox.setType(shippedBatch.getType());
			shippedBox.setBatchCode(shippedBatch.getBatchCode());
			shippedBox.setSkuType(shippedBoxSkus.size());
			shippedBoxDao.save(shippedBox);
			shippedBatch.setBoxQty(shippedBatch.getBoxQty() + 1);// 箱子数量增加
			List<BackupTaskSku> backupTaskSkus=this.backupTaskSkuDao.findByBackupTaskCodeAndStatus(backupTaskCode, "pending");
			if (backupTaskSkus.isEmpty()) {
				shippedBatch.setBoxStatus("finish");
				backupTask.setStatus("finish");//完成装箱操作
				backupTaskDao.save(backupTask);
			}
			shippedBatchDao.save(shippedBatch);
		} catch (Exception e) {
			throw e;
		}
		return shippedBox;
	}
}
